//
//  COHttpManager.swift
//  CocoProject
//
//  Created by Vill on 2023/11/6.
//

import UIKit
import HandyJSON
import Moya

typealias HttpSuccess<T: HandyJSON> = (_ code: Int?,_ object:T?,_ success:Bool?)->Void
typealias HttpFailed = (_ code: Int?, _ msg:String?) -> Void


struct CORespond<T: HandyJSON>: HandyJSON {
    var success: Bool = false
    var code: Int = 0
    var message: String = ""
    var dataModel: T?
    var data:String = ""
    mutating func mapping(mapper: HelpingMapper) {
        mapper <<<
            self.dataModel <-- "dataModel"
    }
}


private let provider = MoyaProvider<MultiTarget>(endpointClosure: endpointClosure, requestClosure: requestClosure, plugins: [networkPlugin], trackInflights: false)

private var requestTimeOut: Double = 30

private let endpointClosure = {(target: TargetType) -> Endpoint in
    let url = target.baseURL.absoluteString + target.path
    var task = target.task
    
    var endPoint = Endpoint(url: url,
                            sampleResponseClosure: { .networkResponse(200, target.sampleData) },
                            method: target.method,
                            task: task,
                            httpHeaderFields: target.headers)
    if let apiTarget = target as? MultiTarget,
       let tar = apiTarget.target as? COBaseApi  {
        switch tar {
        case .queryUser:
            requestTimeOut = 20
            return endPoint
        default:
            return endPoint
        }
    }
    return endPoint
}
/// 网络请求的设置
private let requestClosure = { (endpoint: Endpoint, done: MoyaProvider.RequestResultClosure) in
    do {
        var request = try endpoint.urlRequest()
        // 设置请求时长
        request.timeoutInterval = requestTimeOut
        // 打印请求参数
        if let requestData = request.httpBody {
            print("请求的url：\(request.url!)" + "\n" + "\(request.httpMethod ?? "")" + "发送参数" + "\(String(data: request.httpBody!, encoding: String.Encoding.utf8) ?? "")")
        } else {
            print("请求的url：\(request.url!)" + "\(String(describing: request.httpMethod))")
        }
        if let header = request.allHTTPHeaderFields {
            print("请求头内容\(header)")
        }
        
        done(.success(request))
    } catch {
        done(.failure(MoyaError.underlying(error, nil)))
    }
}
/// NetworkActivityPlugin插件用来监听网络请求，界面上做相应的展示
/// 但这里我没怎么用这个。。。 loading的逻辑直接放在网络处理里面了
private let networkPlugin = NetworkActivityPlugin.init { changeType, _ in
    // targetType 是当前请求的基本信息
    switch changeType {
    case .began:
        print("------------ 开始请求网络 -------------")
    case .ended:
        print("------------ 结束 ---------------")
    }
}

class COHttpManager: NSObject {
    
    private static let msgNetError = "Network Error"

    class func request<T:HandyJSON>(target: TargetType,
                                    modelType: T.Type,
                                    successBlock: @escaping HttpSuccess<T>,
                                    failureBlock: @escaping HttpFailed){
        provider.request(MultiTarget(target)) { result in
            switch result {
            case let .success(response):
                if let json = try? response.mapString() {
                    var result:CORespond<T>?
                    result = CORespond.deserialize(from: json)
                    if (target.path.contains("phoneserialnumber/query") || target.path.contains("user/logout") || target.path.contains("delete") || target.path.contains("bind/free") || target.path.contains("consume/gift") || target.path.contains("consume/call/v4") || target.path.contains("consume/chat")){
                        return successBlock(result?.code,result?.dataModel, result?.success)
                    }
                    if result?.success == true{
                        if let data = result?.data {
                            let r = COAesUtil.aesDecrypt(data)
                            if r.count > 0 {
                                result?.dataModel = T.deserialize(from: r)
                                print("返回结果:****** \n-------- \(r) ----------- ****** \n")
                            }
                            return successBlock(result?.code,result?.dataModel, result?.success)
                        }else {
                            return successBlock(result?.code,nil, result?.success)
                        }
                    }else {
                        let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
                        if result?.code == 1000 && feed == false {
//                            DGUserManager.dgClearInfo()
//                            KAppDelegate.changeRootViewController()
                            NotificationCenter.default.post(name: .QuitAppTimeStopNotification, object: nil)
                            kIsAllreadyCalled.keySaveToNSDefaults(with: false)
                        }else{
                            return failureBlock(result?.code, result?.message)
                        }
                    }
                }
            case let .failure(error):
                print("failure\(error.localizedDescription)")
                return failureBlock(-1, msgNetError)
            }
        }
    }
}
